package com.orangelife.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.ContextResolver;

import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonParser.Feature;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.util.JSONPObject;
import org.codehaus.jackson.type.JavaType;

public class CommJsonProvider extends JacksonJsonProvider {
	
	


	 public ObjectMapper locateMapper(Class<?> type, MediaType mediaType)
	    {
		 

	        // First: were we configured with a specific instance?
	        ObjectMapper m = _mapperConfig.getConfiguredMapper();
	        
	   
	        if (m == null) {
	            // If not, maybe we can get one configured via context?
	            if (_providers != null) {
	                ContextResolver<ObjectMapper> resolver = _providers.getContextResolver(ObjectMapper.class, mediaType);
	                /* Above should work as is, but due to this bug
	                 *   [https://jersey.dev.java.net/issues/show_bug.cgi?id=288]
	                 * in Jersey, it doesn't. But this works until resolution of
	                 * the issue:
	                 */
	                if (resolver == null) {
	                    resolver = _providers.getContextResolver(ObjectMapper.class, null);
	                }
	                if (resolver != null) {
	                    m = resolver.getContext(type);
	                }
	            }
	            if (m == null) {
	                // If not, let's get the fallback default instance
	                m = _mapperConfig.getDefaultMapper();
	            }
	        }
	        m.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);  
	        // 数字也加引号  
	        m.configure(org.codehaus.jackson.JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, true);  
	        m.configure(org.codehaus.jackson.JsonGenerator.Feature.QUOTE_NON_NUMERIC_NUMBERS, true);  
	        
	        return m;
	    }
	
	 @Override
	    public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
	            MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) 
	        throws IOException
	    {
		 
	//	 System.out.println(1212112);
	        /* 27-Feb-2009, tatu: Where can we find desired encoding? Within
	         *   HTTP headers?
	         */
	        ObjectMapper mapper = locateMapper(type, mediaType);
	        
	
	        
	        JsonEncoding enc = findEncoding(mediaType, httpHeaders);
	        JsonGenerator jg = mapper.getJsonFactory().createJsonGenerator(entityStream, enc);
	        jg.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);

	        // Want indentation?
	        if (mapper.getSerializationConfig().isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {
	            jg.useDefaultPrettyPrinter();
	        }
	        // 04-Mar-2010, tatu: How about type we were given? (if any)
	        JavaType rootType = null;
	        
	        if (genericType != null && value != null) {
	            /* 10-Jan-2011, tatu: as per [JACKSON-456], it's not safe to just force root
	             *    type since it prevents polymorphic type serialization. Since we really
	             *    just need this for generics, let's only use generic type if it's truly
	             *    generic.
	             */
	            if (genericType.getClass() != Class.class) { // generic types are other impls of 'java.lang.reflect.Type'
	                /* This is still not exactly right; should root type be further
	                 * specialized with 'value.getClass()'? Let's see how well this works before
	                 * trying to come up with more complete solution.
	                 */
	                rootType = mapper.getTypeFactory().constructType(genericType);
	                /* 26-Feb-2011, tatu: To help with [JACKSON-518], we better recognize cases where
	                 *    type degenerates back into "Object.class" (as is the case with plain TypeVariable,
	                 *    for example), and not use that.
	                 */
	                if (rootType.getRawClass() == Object.class) {
	                    rootType = null;
	                }
	            }
	        }
	        // [JACKSON-578]: Allow use of @JsonView in resource methods.
	        Class<?> viewToUse = null;
	        if (annotations != null && annotations.length > 0) {
	            viewToUse = _findView(mapper, annotations);
	        }
	        if (viewToUse != null) {
	            // TODO: change to use 'writerWithType' for 2.0 (1.9 could use, but let's defer)
	            ObjectWriter viewWriter = mapper.viewWriter(viewToUse);
	            // [JACKSON-245] Allow automatic JSONP wrapping
	            if (_jsonpFunctionName != null) {
	                viewWriter.writeValue(jg, new JSONPObject(this._jsonpFunctionName, value, rootType));
	            } else if (rootType != null) {
	                // TODO: change to use 'writerWithType' for 2.0 (1.9 could use, but let's defer)
	                mapper.typedWriter(rootType).withView(viewToUse).writeValue(jg, value);
	            } else {
	                viewWriter.writeValue(jg, value);
	            }
	        } else {
	            // [JACKSON-245] Allow automatic JSONP wrapping
	            if (_jsonpFunctionName != null) {
	                mapper.writeValue(jg, new JSONPObject(this._jsonpFunctionName, value, rootType));
	            } else if (rootType != null) {
	                // TODO: change to use 'writerWithType' for 2.0 (1.9 could use, but let's defer)
	                mapper.typedWriter(rootType).writeValue(jg, value);
	            } else {
	                mapper.writeValue(jg, value);
	            }
	        }
	    }
	
	

}
